import { HResponseTransformInterceptor } from './interceptor/response.interceptor';
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
import { DocumentBuilder, SwaggerModule } from '@nestjs/swagger';
import { AppModule } from './app.module';
import { HExceptionFilter } from './filters/exception.filter';
import { HLoggerInterceptor } from './interceptor/logger.interceptor';
import { HValidationPipe } from './pipe/validation.pipe';
import CONFIG from './config';
import { HLogger } from './logger';
import { ROUTER_PREFIX } from './constants';

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule, {
    // 关闭默认日志
    // logger: false,
    // 所有的日志都会被放入缓冲区，直到一个自定义的日志记录器被接入
    // bufferLogs: true,
    // 设置跨域访问
    cors: true,
  });
  // app.useLogger(app.get(HLogger));
  // 全局路由前缀
  app.setGlobalPrefix(ROUTER_PREFIX);

  // apidoc 可在浏览器里访问 http://127.0.0.1:3000/apidoc
  const config = new DocumentBuilder()
    .setTitle('Nestjs Api Docs')
    .setDescription('Nestjs Api Docs')
    .setVersion('1.0')
    .build();
  const document = SwaggerModule.createDocument(app, config);
  SwaggerModule.setup('apidoc', app, document);

  // 全局统一返回格式拦截器
  app.useGlobalInterceptors(new HResponseTransformInterceptor());
  /**
   * 拦截器与异常过滤器区别
   * 1. 时机不同，拦截器的执行顺序在异常过滤器之前，这意味着拦截器抛出的错误，最后可经由过滤器处理
   * 2. 对象不同，拦截器捕获的是 routerHandler 抛出的所有异常，而异常过滤器可通过 @Catch(SomeException) 来捕获特定的异常
   */
  // 自定义管道实现路由参数校验
  app.useGlobalPipes(new HValidationPipe());
  // 全局日志拦截
  app.useGlobalInterceptors(new HLoggerInterceptor());
  // 全局异常过滤器
  app.useGlobalFilters(new HExceptionFilter());

  // 端口
  await app.listen(CONFIG.port, () => {
    console.log(`>>>>>>>>>>>   Server is running on port ${CONFIG.port} ...`);
  });
}
bootstrap();
